"""
攻击服务器的一种邪恶的方式：
用多进程多线程多协程去请求轰炸服务器(流量轰炸)
由于网站的带宽是有限的  你去轰炸会让服务器一直处于响应状态  别人就无法访问
常用的反制手段就是封ip

所以我们需要对协程的并发任务进行限制(加一个锁限制任务并发数)

"""
import time
import asyncio  #协程模块

#async关键字 申明协程函数 告诉解释器  我这刚函数里面会发生阻塞 你要走开  并且在会发生阻塞的地方使用await
async def send_request(url,semaphore):
    async with semaphore:   #对任务加上一层锁对象 如果并发数超过锁对象就等待
        await asyncio.sleep(3)  # 协程函数必需要搭配异步请求，异步任务  requests同步请求库是不能用的
        print(url)


if __name__ == '__main__':
    # 先请求目录
    urls = [
        'https://www.xunter.com/1',
        'https://www.xunter.com/2',
        'https://www.xunter.com/3',
        'https://www.xunter.com/4',
        'https://www.xunter.com/5',
        'https://www.xunter.com/6',
        'https://www.xunter.com/7',
        'https://www.xunter.com/8',
        'https://www.xunter.com/9',
        'https://www.xunter.com/10',

    ]

    start = time.time()  # 开始运行的时间戳
    print('开始:', start)

    # print(send_request(1))    #直接调用方法返回的是一个协程对象  一个协程对象可以说是一个方法
    #获取默认事件循环对象  处理协程对象  轮询每一个方法的执行状态
    loop = asyncio.get_event_loop()    # 1.获取默认事件对象

    semaphore = asyncio.Semaphore(6)    #限制并发任务数6  创建锁对象

    tasks = [send_request(url,semaphore) for url in urls]  # 2.构建任务协程对象  并且传入锁对象

    loop.run_until_complete(asyncio.wait(tasks))   # 3.执行协程任务，并让事件循环对象开始工作

    loop.close()    #4.释放

    end = time.time()
    print('结束：', end, '耗时：', end - start)